home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / WarpQuake / Src / net_dgrm.c < prev    next >
C/C++ Source or Header  |  2000-05-22  |  33KB  |  1,391 lines

  1. /*
  2. Copyright (C) 1996-1997 Id Software, Inc.
  3.  
  4. This program is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU General Public License
  6. as published by the Free Software Foundation; either version 2
  7. of the License, or (at your option) any later version.
  8.  
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
  12.  
  13. See the GNU General Public License for more details.
  14.  
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  18.  
  19. */
  20. // net_dgrm.c
  21.  
  22. // This is enables a simple IP banning mechanism
  23. //#define BAN_TEST
  24.  
  25. #ifdef BAN_TEST
  26. #if defined(_WIN32)
  27. #include <windows.h>
  28. #elif defined (NeXT)
  29. #include <sys/socket.h>
  30. #include <arpa/inet.h>
  31. #else
  32. #define AF_INET         2    /* internet */
  33. struct in_addr
  34. {
  35.     union
  36.     {
  37.         struct { unsigned char s_b1,s_b2,s_b3,s_b4; } S_un_b;
  38.         struct { unsigned short s_w1,s_w2; } S_un_w;
  39.         unsigned long S_addr;
  40.     } S_un;
  41. };
  42. #define    s_addr    S_un.S_addr    /* can be used for most tcp & ip code */
  43. struct sockaddr_in
  44. {
  45.     short            sin_family;
  46.     unsigned short    sin_port;
  47.     struct in_addr    sin_addr;
  48.     char            sin_zero[8];
  49. };
  50. char *inet_ntoa(struct in_addr in);
  51. unsigned long inet_addr(const char *cp);
  52. #endif
  53. #endif    // BAN_TEST
  54.  
  55. #include "quakedef.h"
  56. #include "net_dgrm.h"
  57.  
  58. // these two macros are to make the code more readable
  59. #define sfunc    net_landrivers[sock->landriver]
  60. #define dfunc    net_landrivers[net_landriverlevel]
  61.  
  62. static int net_landriverlevel;
  63.  
  64. /* statistic counters */
  65. int    packetsSent = 0;
  66. int    packetsReSent = 0;
  67. int packetsReceived = 0;
  68. int receivedDuplicateCount = 0;
  69. int shortPacketCount = 0;
  70. int droppedDatagrams;
  71.  
  72. static int myDriverLevel;
  73.  
  74. struct
  75. {
  76.     unsigned int    length;
  77.     unsigned int    sequence;
  78.     byte            data[MAX_DATAGRAM];
  79. } packetBuffer;
  80.  
  81. extern int m_return_state;
  82. extern int m_state;
  83. extern qboolean m_return_onerror;
  84. extern char m_return_reason[32];
  85.  
  86.  
  87. #ifdef DEBUG
  88. char *StrAddr (struct qsockaddr *addr)
  89. {
  90.     static char buf[34];
  91.     byte *p = (byte *)addr;
  92.     int n;
  93.  
  94.     for (n = 0; n < 16; n++)
  95.         sprintf (buf + n * 2, "%02x", *p++);
  96.     return buf;
  97. }
  98. #endif
  99.  
  100.  
  101. #ifdef BAN_TEST
  102. unsigned long banAddr = 0x00000000;
  103. unsigned long banMask = 0xffffffff;
  104.  
  105. void NET_Ban_f (void)
  106. {
  107.     char    addrStr [32];
  108.     char    maskStr [32];
  109.     void    (*print) (char *fmt, ...);
  110.  
  111.     if (cmd_source == src_command)
  112.     {
  113.         if (!sv.active)
  114.         {
  115.             Cmd_ForwardToServer ();
  116.             return;
  117.         }
  118.         print = Con_Printf;
  119.     }
  120.     else
  121.     {
  122.         if (pr_global_struct->deathmatch && !host_client->privileged)
  123.             return;
  124.         print = SV_ClientPrintf;
  125.     }
  126.  
  127.     switch (Cmd_Argc ())
  128.     {
  129.         case 1:
  130.             if (((struct in_addr *)&banAddr)->s_addr)
  131.             {
  132.                 Q_strcpy(addrStr, inet_ntoa(*(struct in_addr *)&banAddr));
  133.                 Q_strcpy(maskStr, inet_ntoa(*(struct in_addr *)&banMask));
  134.                 print("Banning %s [%s]\n", addrStr, maskStr);
  135.             }
  136.             else
  137.                 print("Banning not active\n");
  138.             break;
  139.  
  140.         case 2:
  141.             if (Q_strcasecmp(Cmd_Argv(1), "off") == 0)
  142.                 banAddr = 0x00000000;
  143.             else
  144.                 banAddr = inet_addr(Cmd_Argv(1));
  145.             banMask = 0xffffffff;
  146.             break;
  147.  
  148.         case 3:
  149.             banAddr = inet_addr(Cmd_Argv(1));
  150.             banMask = inet_addr(Cmd_Argv(2));
  151.             break;
  152.  
  153.         default:
  154.             print("BAN ip_address [mask]\n");
  155.             break;
  156.     }
  157. }
  158. #endif
  159.  
  160.  
  161. int Datagram_SendMessage (qsocket_t *sock, sizebuf_t *data)
  162. {
  163.     unsigned int    packetLen;
  164.     unsigned int    dataLen;
  165.     unsigned int    eom;
  166.  
  167. #ifdef DEBUG
  168.     if (data->cursize == 0)
  169.         Sys_Error("Datagram_SendMessage: zero length message\n");
  170.  
  171.     if (data->cursize > NET_MAXMESSAGE)
  172.         Sys_Error("Datagram_SendMessage: message too big %u\n", data->cursize);
  173.  
  174.     if (sock->canSend == false)
  175.         Sys_Error("SendMessage: called with canSend == false\n");
  176. #endif
  177.  
  178.     Q_memcpy(sock->sendMessage, data->data, data->cursize);
  179.     sock->sendMessageLength = data->cursize;
  180.  
  181.     if (data->cursize <= MAX_DATAGRAM)
  182.     {
  183.         dataLen = data->cursize;
  184.         eom = NETFLAG_EOM;
  185.     }
  186.     else
  187.     {
  188.         dataLen = MAX_DATAGRAM;
  189.         eom = 0;
  190.     }
  191.     packetLen = NET_HEADERSIZE + dataLen;
  192.  
  193.     packetBuffer.length = BigLong(packetLen | (NETFLAG_DATA | eom));
  194.     packetBuffer.sequence = BigLong(sock->sendSequence++);
  195.     Q_memcpy (packetBuffer.data, sock->sendMessage, dataLen);
  196.  
  197.     sock->canSend = false;
  198.  
  199.     if (sfunc.Write (sock->socket, (byte *)&packetBuffer, packetLen, &sock->addr) == -1)
  200.         return -1;
  201.  
  202.     sock->lastSendTime = net_time;
  203.     packetsSent++;
  204.     return 1;
  205. }
  206.  
  207.  
  208. int SendMessageNext (qsocket_t *sock)
  209. {
  210.     unsigned int    packetLen;
  211.     unsigned int    dataLen;
  212.     unsigned int    eom;
  213.  
  214.     if (sock->sendMessageLength <= MAX_DATAGRAM)
  215.     {
  216.         dataLen = sock->sendMessageLength;
  217.         eom = NETFLAG_EOM;
  218.     }
  219.     else
  220.     {
  221.         dataLen = MAX_DATAGRAM;
  222.         eom = 0;
  223.     }
  224.     packetLen = NET_HEADERSIZE + dataLen;
  225.  
  226.     packetBuffer.length = BigLong(packetLen | (NETFLAG_DATA | eom));
  227.     packetBuffer.sequence = BigLong(sock->sendSequence++);
  228.     Q_memcpy (packetBuffer.data, sock->sendMessage, dataLen);
  229.  
  230.     sock->sendNext = false;
  231.  
  232.     if (sfunc.Write (sock->socket, (byte *)&packetBuffer, packetLen, &sock->addr) == -1)
  233.         return -1;
  234.  
  235.     sock->lastSendTime = net_time;
  236.     packetsSent++;
  237.     return 1;
  238. }
  239.  
  240.  
  241. int ReSendMessage (qsocket_t *sock)
  242. {
  243.     unsigned int    packetLen;
  244.     unsigned int    dataLen;
  245.     unsigned int    eom;
  246.  
  247.     if (sock->sendMessageLength <= MAX_DATAGRAM)
  248.     {
  249.         dataLen = sock->sendMessageLength;
  250.         eom = NETFLAG_EOM;
  251.     }
  252.     else
  253.     {
  254.         dataLen = MAX_DATAGRAM;
  255.         eom = 0;
  256.     }
  257.     packetLen = NET_HEADERSIZE + dataLen;
  258.  
  259.     packetBuffer.length = BigLong(packetLen | (NETFLAG_DATA | eom));
  260.     packetBuffer.sequence = BigLong(sock->sendSequence - 1);
  261.     Q_memcpy (packetBuffer.data, sock->sendMessage, dataLen);
  262.  
  263.     sock->sendNext = false;
  264.  
  265.     if (sfunc.Write (sock->socket, (byte *)&packetBuffer, packetLen, &sock->addr) == -1)
  266.         return -1;
  267.  
  268.     sock->lastSendTime = net_time;
  269.     packetsReSent++;
  270.     return 1;
  271. }
  272.  
  273.  
  274. qboolean Datagram_CanSendMessage (qsocket_t *sock)
  275. {
  276.     if (sock->sendNext)
  277.         SendMessageNext (sock);
  278.  
  279.     return sock->canSend;
  280. }
  281.  
  282.  
  283. qboolean Datagram_CanSendUnreliableMessage (qsocket_t *sock)
  284. {
  285.     return true;
  286. }
  287.  
  288.  
  289. int Datagram_SendUnreliableMessage (qsocket_t *sock, sizebuf_t *data)
  290. {
  291.     int     packetLen;
  292.  
  293. #ifdef DEBUG
  294.     if (data->cursize == 0)
  295.         Sys_Error("Datagram_SendUnreliableMessage: zero length message\n");
  296.  
  297.     if (data->cursize > MAX_DATAGRAM)
  298.         Sys_Error("Datagram_SendUnreliableMessage: message too big %u\n", data->cursize);
  299. #endif
  300.  
  301.     packetLen = NET_HEADERSIZE + data->cursize;
  302.  
  303.     packetBuffer.length = BigLong(packetLen | NETFLAG_UNRELIABLE);
  304.     packetBuffer.sequence = BigLong(sock->unreliableSendSequence++);
  305.     Q_memcpy (packetBuffer.data, data->data, data->cursize);
  306.  
  307.     if (sfunc.Write (sock->socket, (byte *)&packetBuffer, packetLen, &sock->addr) == -1)
  308.         return -1;
  309.  
  310.     packetsSent++;
  311.     return 1;
  312. }
  313.  
  314.  
  315. int    Datagram_GetMessage (qsocket_t *sock)
  316. {
  317.     unsigned int    length;
  318.     unsigned int    flags;
  319.     int                ret = 0;
  320.     struct qsockaddr readaddr;
  321.     unsigned int    sequence;
  322.     unsigned int    count;
  323.  
  324.     if (!sock->canSend)
  325.         if ((net_time - sock->lastSendTime) > 1.0)
  326.             ReSendMessage (sock);
  327.  
  328.     while(1)
  329.     {    
  330.         length = sfunc.Read (sock->socket, (byte *)&packetBuffer, NET_DATAGRAMSIZE, &readaddr);
  331.  
  332. //    if ((rand() & 255) > 220)
  333. //        continue;
  334.  
  335.         if (length == 0)
  336.             break;
  337.  
  338.         if (length == -1)
  339.         {
  340.             Con_Printf("Read error\n");
  341.             return -1;
  342.         }
  343.  
  344.         if (sfunc.AddrCompare(&readaddr, &sock->addr) != 0)
  345.         {
  346. #ifdef DEBUG
  347.             Con_DPrintf("Forged packet received\n");
  348.             Con_DPrintf("Expected: %s\n", StrAddr (&sock->addr));
  349.             Con_DPrintf("Received: %s\n", StrAddr (&readaddr));
  350. #endif
  351.             continue;
  352.         }
  353.  
  354.         if (length < NET_HEADERSIZE)
  355.         {
  356.             shortPacketCount++;
  357.             continue;
  358.         }
  359.  
  360.         length = BigLong(packetBuffer.length);
  361.         flags = length & (~NETFLAG_LENGTH_MASK);
  362.         length &= NETFLAG_LENGTH_MASK;
  363.  
  364.         if (flags & NETFLAG_CTL)
  365.             continue;
  366.  
  367.         sequence = BigLong(packetBuffer.sequence);
  368.         packetsReceived++;
  369.  
  370.         if (flags & NETFLAG_UNRELIABLE)
  371.         {
  372.             if (sequence < sock->unreliableReceiveSequence)
  373.             {
  374.                 Con_DPrintf("Got a stale datagram\n");
  375.                 ret = 0;
  376.                 break;
  377.             }
  378.             if (sequence != sock->unreliableReceiveSequence)
  379.             {
  380.                 count = sequence - sock->unreliableReceiveSequence;
  381.                 droppedDatagrams += count;
  382.                 Con_DPrintf("Dropped %u datagram(s)\n", count);
  383.             }
  384.             sock->unreliableReceiveSequence = sequence + 1;
  385.  
  386.             length -= NET_HEADERSIZE;
  387.  
  388.             SZ_Clear (&net_message);
  389.             SZ_Write (&net_message, packetBuffer.data, length);
  390.  
  391.             ret = 2;
  392.             break;
  393.         }
  394.  
  395.         if (flags & NETFLAG_ACK)
  396.         {
  397.             if (sequence != (sock->sendSequence - 1))
  398.             {
  399.                 Con_DPrintf("Stale ACK received\n");
  400.                 continue;
  401.             }
  402.             if (sequence == sock->ackSequence)
  403.             {
  404.                 sock->ackSequence++;
  405.                 if (sock->ackSequence != sock->sendSequence)
  406.                     Con_DPrintf("ack sequencing error\n");
  407.             }
  408.             else
  409.             {
  410.                 Con_DPrintf("Duplicate ACK received\n");
  411.                 continue;
  412.             }
  413.             sock->sendMessageLength -= MAX_DATAGRAM;
  414.             if (sock->sendMessageLength > 0)
  415.             {
  416.                 Q_memcpy(sock->sendMessage, sock->sendMessage+MAX_DATAGRAM, sock->sendMessageLength);
  417.                 sock->sendNext = true;
  418.             }
  419.             else
  420.             {
  421.                 sock->sendMessageLength = 0;
  422.                 sock->canSend = true;
  423.             }
  424.             continue;
  425.         }
  426.  
  427.         if (flags & NETFLAG_DATA)
  428.         {
  429.             packetBuffer.length = BigLong(NET_HEADERSIZE | NETFLAG_ACK);
  430.             packetBuffer.sequence = BigLong(sequence);
  431.             sfunc.Write (sock->socket, (byte *)&packetBuffer, NET_HEADERSIZE, &readaddr);
  432.  
  433.             if (sequence != sock->receiveSequence)
  434.             {
  435.                 receivedDuplicateCount++;
  436.                 continue;
  437.             }
  438.             sock->receiveSequence++;
  439.  
  440.             length -= NET_HEADERSIZE;
  441.  
  442.             if (flags & NETFLAG_EOM)
  443.             {
  444.                 SZ_Clear(&net_message);
  445.                 SZ_Write(&net_message, sock->receiveMessage, sock->receiveMessageLength);
  446.                 SZ_Write(&net_message, packetBuffer.data, length);
  447.                 sock->receiveMessageLength = 0;
  448.  
  449.                 ret = 1;
  450.                 break;
  451.             }
  452.  
  453.             Q_memcpy(sock->receiveMessage + sock->receiveMessageLength, packetBuffer.data, length);
  454.             sock->receiveMessageLength += length;
  455.             continue;
  456.         }
  457.     }
  458.  
  459.     if (sock->sendNext)
  460.         SendMessageNext (sock);
  461.  
  462.     return ret;
  463. }
  464.  
  465.  
  466. void PrintStats(qsocket_t *s)
  467. {
  468.     Con_Printf("canSend = %4u   \n", s->canSend);
  469.     Con_Printf("sendSeq = %4u   ", s->sendSequence);
  470.     Con_Printf("recvSeq = %4u   \n", s->receiveSequence);
  471.     Con_Printf("\n");
  472. }
  473.  
  474. void NET_Stats_f (void)
  475. {
  476.     qsocket_t    *s;
  477.  
  478.     if (Cmd_Argc () == 1)
  479.     {
  480.         Con_Printf("unreliable messages sent   = %i\n", unreliableMessagesSent);
  481.         Con_Printf("unreliable messages recv   = %i\n", unreliableMessagesReceived);
  482.         Con_Printf("reliable messages sent     = %i\n", messagesSent);
  483.         Con_Printf("reliable messages received = %i\n", messagesReceived);
  484.         Con_Printf("packetsSent                = %i\n", packetsSent);
  485.         Con_Printf("packetsReSent              = %i\n", packetsReSent);
  486.         Con_Printf("packetsReceived            = %i\n", packetsReceived);
  487.         Con_Printf("receivedDuplicateCount     = %i\n", receivedDuplicateCount);
  488.         Con_Printf("shortPacketCount           = %i\n", shortPacketCount);
  489.         Con_Printf("droppedDatagrams           = %i\n", droppedDatagrams);
  490.     }
  491.     else if (Q_strcmp(Cmd_Argv(1), "*") == 0)
  492.     {
  493.         for (s = net_activeSockets; s; s = s->next)
  494.             PrintStats(s);
  495.         for (s = net_freeSockets; s; s = s->next)
  496.             PrintStats(s);
  497.     }
  498.     else
  499.     {
  500.         for (s = net_activeSockets; s; s = s->next)
  501.             if (Q_strcasecmp(Cmd_Argv(1), s->address) == 0)
  502.                 break;
  503.         if (s == NULL)
  504.             for (s = net_freeSockets; s; s = s->next)
  505.                 if (Q_strcasecmp(Cmd_Argv(1), s->address) == 0)
  506.                     break;
  507.         if (s == NULL)
  508.             return;
  509.         PrintStats(s);
  510.     }
  511. }
  512.  
  513.  
  514. static qboolean testInProgress = false;
  515. static int        testPollCount;
  516. static int        testDriver;
  517. static int        testSocket;
  518.  
  519. static void Test_Poll(void);
  520. PollProcedure    testPollProcedure = {NULL, 0.0, Test_Poll};
  521.  
  522. static void Test_Poll(void)
  523. {
  524.     struct qsockaddr clientaddr;
  525.     int        control;
  526.     int        len;
  527.     char    name[32];
  528.     char    address[64];
  529.     int        colors;
  530.     int        frags;
  531.     int        connectTime;
  532.     byte    playerNumber;
  533.  
  534.     net_landriverlevel = testDriver;
  535.  
  536.     while (1)
  537.     {
  538.         len = dfunc.Read (testSocket, net_message.data, net_message.maxsize, &clientaddr);
  539.         if (len < sizeof(int))
  540.             break;
  541.  
  542.         net_message.cursize = len;
  543.  
  544.         MSG_BeginReading ();
  545.         control = BigLong(*((int *)net_message.data));
  546.         MSG_ReadLong();
  547.         if (control == -1)
  548.             break;
  549.         if ((control & (~NETFLAG_LENGTH_MASK)) !=  NETFLAG_CTL)
  550.             break;
  551.         if ((control & NETFLAG_LENGTH_MASK) != len)
  552.             break;
  553.  
  554.         if (MSG_ReadByte() != CCREP_PLAYER_INFO)
  555.             Sys_Error("Unexpected repsonse to Player Info request\n");
  556.  
  557.         playerNumber = MSG_ReadByte();
  558.         Q_strcpy(name, MSG_ReadString());
  559.         colors = MSG_ReadLong();
  560.         frags = MSG_ReadLong();
  561.         connectTime = MSG_ReadLong();
  562.         Q_strcpy(address, MSG_ReadString());
  563.  
  564.         Con_Printf("%s\n  frags:%3i  colors:%u %u  time:%u\n  %s\n", name, frags, colors >> 4, colors & 0x0f, connectTime / 60, address);
  565.     }
  566.  
  567.     testPollCount--;
  568.     if (testPollCount)
  569.     {
  570.         SchedulePollProcedure(&testPollProcedure, 0.1);
  571.     }
  572.     else
  573.     {
  574.         dfunc.CloseSocket(testSocket);
  575.         testInProgress = false;
  576.     }
  577. }
  578.  
  579. static void Test_f (void)
  580. {
  581.     char    *host;
  582.     int        n;
  583.     int        max = MAX_SCOREBOARD;
  584.     struct qsockaddr sendaddr;
  585.  
  586.     if (testInProgress)
  587.         return;
  588.  
  589.     host = Cmd_Argv (1);
  590.  
  591.     if (host && hostCacheCount)
  592.     {
  593.         for (n = 0; n < hostCacheCount; n++)
  594.             if (Q_strcasecmp (host, hostcache[n].name) == 0)
  595.             {
  596.                 if (hostcache[n].driver != myDriverLevel)
  597.                     continue;
  598.                 net_landriverlevel = hostcache[n].ldriver;
  599.                 max = hostcache[n].maxusers;
  600.                 Q_memcpy(&sendaddr, &hostcache[n].addr, sizeof(struct qsockaddr));
  601.                 break;
  602.             }
  603.         if (n < hostCacheCount)
  604.             goto JustDoIt;
  605.     }
  606.  
  607.     for (net_landriverlevel = 0; net_landriverlevel < net_numlandrivers; net_landriverlevel++)
  608.     {
  609.         if (!net_landrivers[net_landriverlevel].initialized)
  610.             continue;
  611.  
  612.         // see if we can resolve the host name
  613.         if (dfunc.GetAddrFromName(host, &sendaddr) != -1)
  614.             break;
  615.     }
  616.     if (net_landriverlevel == net_numlandrivers)
  617.         return;
  618.  
  619. JustDoIt:
  620.     testSocket = dfunc.OpenSocket(0);
  621.     if (testSocket == -1)
  622.         return;
  623.  
  624.     testInProgress = true;
  625.     testPollCount = 20;
  626.     testDriver = net_landriverlevel;
  627.  
  628.     for (n = 0; n < max; n++)
  629.     {
  630.         SZ_Clear(&net_message);
  631.         // save space for the header, filled in later
  632.         MSG_WriteLong(&net_message, 0);
  633.         MSG_WriteByte(&net_message, CCREQ_PLAYER_INFO);
  634.         MSG_WriteByte(&net_message, n);
  635.         *((int *)net_message.data) = BigLong(NETFLAG_CTL |     (net_message.cursize & NETFLAG_LENGTH_MASK));
  636.         dfunc.Write (testSocket, net_message.data, net_message.cursize, &sendaddr);
  637.     }
  638.     SZ_Clear(&net_message);
  639.     SchedulePollProcedure(&testPollProcedure, 0.1);
  640. }
  641.  
  642.  
  643. static qboolean test2InProgress = false;
  644. static int        test2Driver;
  645. static int        test2Socket;
  646.  
  647. static void Test2_Poll(void);
  648. PollProcedure    test2PollProcedure = {NULL, 0.0, Test2_Poll};
  649.  
  650. static void Test2_Poll(void)
  651. {
  652.     struct qsockaddr clientaddr;
  653.     int        control;
  654.     int        len;
  655.     char    name[256];
  656.     char    value[256];
  657.  
  658.     net_landriverlevel = test2Driver;
  659.     name[0] = 0;
  660.  
  661.     len = dfunc.Read (test2Socket, net_message.data, net_message.maxsize, &clientaddr);
  662.     if (len < sizeof(int))
  663.         goto Reschedule;
  664.  
  665.     net_message.cursize = len;
  666.  
  667.     MSG_BeginReading ();
  668.     control = BigLong(*((int *)net_message.data));
  669.     MSG_ReadLong();
  670.     if (control == -1)
  671.         goto Error;
  672.     if ((control & (~NETFLAG_LENGTH_MASK)) !=  NETFLAG_CTL)
  673.         goto Error;
  674.     if ((control & NETFLAG_LENGTH_MASK) != len)
  675.         goto Error;
  676.  
  677.     if (MSG_ReadByte() != CCREP_RULE_INFO)
  678.         goto Error;
  679.  
  680.     Q_strcpy(name, MSG_ReadString());
  681.     if (name[0] == 0)
  682.         goto Done;
  683.     Q_strcpy(value, MSG_ReadString());
  684.  
  685.     Con_Printf("%-16.16s  %-16.16s\n", name, value);
  686.  
  687.     SZ_Clear(&net_message);
  688.     // save space for the header, filled in later
  689.     MSG_WriteLong(&net_message, 0);
  690.     MSG_WriteByte(&net_message, CCREQ_RULE_INFO);
  691.     MSG_WriteString(&net_message, name);
  692.     *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
  693.     dfunc.Write (test2Socket, net_message.data, net_message.cursize, &clientaddr);
  694.     SZ_Clear(&net_message);
  695.  
  696. Reschedule:
  697.     SchedulePollProcedure(&test2PollProcedure, 0.05);
  698.     return;
  699.  
  700. Error:
  701.     Con_Printf("Unexpected repsonse to Rule Info request\n");
  702. Done:
  703.     dfunc.CloseSocket(test2Socket);
  704.     test2InProgress = false;
  705.     return;
  706. }
  707.  
  708. static void Test2_f (void)
  709. {
  710.     char    *host;
  711.     int        n;
  712.     struct qsockaddr sendaddr;
  713.  
  714.     if (test2InProgress)
  715.         return;
  716.  
  717.     host = Cmd_Argv (1);
  718.  
  719.     if (host && hostCacheCount)
  720.     {
  721.         for (n = 0; n < hostCacheCount; n++)
  722.             if (Q_strcasecmp (host, hostcache[n].name) == 0)
  723.             {
  724.                 if (hostcache[n].driver != myDriverLevel)
  725.                     continue;
  726.                 net_landriverlevel = hostcache[n].ldriver;
  727.                 Q_memcpy(&sendaddr, &hostcache[n].addr, sizeof(struct qsockaddr));
  728.                 break;
  729.             }
  730.         if (n < hostCacheCount)
  731.             goto JustDoIt;
  732.     }
  733.  
  734.     for (net_landriverlevel = 0; net_landriverlevel < net_numlandrivers; net_landriverlevel++)
  735.     {
  736.         if (!net_landrivers[net_landriverlevel].initialized)
  737.             continue;
  738.  
  739.         // see if we can resolve the host name
  740.         if (dfunc.GetAddrFromName(host, &sendaddr) != -1)
  741.             break;
  742.     }
  743.     if (net_landriverlevel == net_numlandrivers)
  744.         return;
  745.  
  746. JustDoIt:
  747.     test2Socket = dfunc.OpenSocket(0);
  748.     if (test2Socket == -1)
  749.         return;
  750.  
  751.     test2InProgress = true;
  752.     test2Driver = net_landriverlevel;
  753.  
  754.     SZ_Clear(&net_message);
  755.     // save space for the header, filled in later
  756.     MSG_WriteLong(&net_message, 0);
  757.     MSG_WriteByte(&net_message, CCREQ_RULE_INFO);
  758.     MSG_WriteString(&net_message, "");
  759.     *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
  760.     dfunc.Write (test2Socket, net_message.data, net_message.cursize, &sendaddr);
  761.     SZ_Clear(&net_message);
  762.     SchedulePollProcedure(&test2PollProcedure, 0.05);
  763. }
  764.  
  765.  
  766. int Datagram_Init (void)
  767. {
  768.     int i;
  769.     int csock;
  770.  
  771.     myDriverLevel = net_driverlevel;
  772.     Cmd_AddCommand ("net_stats", NET_Stats_f);
  773.  
  774.     if (COM_CheckParm("-nolan"))
  775.         return -1;
  776.  
  777.     for (i = 0; i < net_numlandrivers; i++)
  778.         {
  779.         csock = net_landrivers[i].Init ();
  780.         if (csock == -1)
  781.             continue;
  782.         net_landrivers[i].initialized = true;
  783.         net_landrivers[i].controlSock = csock;
  784.         }
  785.  
  786. #ifdef BAN_TEST
  787.     Cmd_AddCommand ("ban", NET_Ban_f);
  788. #endif
  789.     Cmd_AddCommand ("test", Test_f);
  790.     Cmd_AddCommand ("test2", Test2_f);
  791.  
  792.     return 0;
  793. }
  794.  
  795.  
  796. void Datagram_Shutdown (void)
  797. {
  798.     int i;
  799.  
  800. //
  801. // shutdown the lan drivers
  802. //
  803.     for (i = 0; i < net_numlandrivers; i++)
  804.     {
  805.         if (net_landrivers[i].initialized)
  806.         {
  807.             net_landrivers[i].Shutdown ();
  808.             net_landrivers[i].initialized = false;
  809.         }
  810.     }
  811. }
  812.  
  813.  
  814. void Datagram_Close (qsocket_t *sock)
  815. {
  816.     sfunc.CloseSocket(sock->socket);
  817. }
  818.  
  819.  
  820. void Datagram_Listen (qboolean state)
  821. {
  822.     int i;
  823.  
  824.     for (i = 0; i < net_numlandrivers; i++)
  825.         if (net_landrivers[i].initialized)
  826.             net_landrivers[i].Listen (state);
  827. }
  828.  
  829.  
  830. static qsocket_t *_Datagram_CheckNewConnections (void)
  831. {
  832.     struct qsockaddr clientaddr;
  833.     struct qsockaddr newaddr;
  834.     int            newsock;
  835.     int            acceptsock;
  836.     qsocket_t    *sock;
  837.     qsocket_t    *s;
  838.     int            len;
  839.     int            command;
  840.     int            control;
  841.     int            ret;
  842.  
  843.     acceptsock = dfunc.CheckNewConnections();
  844.     if (acceptsock == -1)
  845.         return NULL;
  846.  
  847.     SZ_Clear(&net_message);
  848.  
  849.     len = dfunc.Read (acceptsock, net_message.data, net_message.maxsize, &clientaddr);
  850.     if (len < sizeof(int))
  851.         return NULL;
  852.     net_message.cursize = len;
  853.  
  854.     MSG_BeginReading ();
  855.     control = BigLong(*((int *)net_message.data));
  856.     MSG_ReadLong();
  857.     if (control == -1)
  858.         return NULL;
  859.     if ((control & (~NETFLAG_LENGTH_MASK)) !=  NETFLAG_CTL)
  860.         return NULL;
  861.     if ((control & NETFLAG_LENGTH_MASK) != len)
  862.         return NULL;
  863.  
  864.     command = MSG_ReadByte();
  865.     if (command == CCREQ_SERVER_INFO)
  866.     {
  867.         if (Q_strcmp(MSG_ReadString(), "QUAKE") != 0)
  868.             return NULL;
  869.  
  870.         SZ_Clear(&net_message);
  871.         // save space for the header, filled in later
  872.         MSG_WriteLong(&net_message, 0);
  873.         MSG_WriteByte(&net_message, CCREP_SERVER_INFO);
  874.         dfunc.GetSocketAddr(acceptsock, &newaddr);
  875.         MSG_WriteString(&net_message, dfunc.AddrToString(&newaddr));
  876.         MSG_WriteString(&net_message, hostname.string);
  877.         MSG_WriteString(&net_message, sv.name);
  878.         MSG_WriteByte(&net_message, net_activeconnections);
  879.         MSG_WriteByte(&net_message, svs.maxclients);
  880.         MSG_WriteByte(&net_message, NET_PROTOCOL_VERSION);
  881.         *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
  882.         dfunc.Write (acceptsock, net_message.data, net_message.cursize, &clientaddr);
  883.         SZ_Clear(&net_message);
  884.         return NULL;
  885.     }
  886.  
  887.     if (command == CCREQ_PLAYER_INFO)
  888.     {
  889.         int            playerNumber;
  890.         int            activeNumber;
  891.         int            clientNumber;
  892.         client_t    *client;
  893.         
  894.         playerNumber = MSG_ReadByte();
  895.         activeNumber = -1;
  896.         for (clientNumber = 0, client = svs.clients; clientNumber < svs.maxclients; clientNumber++, client++)
  897.         {
  898.             if (client->active)
  899.             {
  900.                 activeNumber++;
  901.                 if (activeNumber == playerNumber)
  902.                     break;
  903.             }
  904.         }
  905.         if (clientNumber == svs.maxclients)
  906.             return NULL;
  907.  
  908.         SZ_Clear(&net_message);
  909.         // save space for the header, filled in later
  910.         MSG_WriteLong(&net_message, 0);
  911.         MSG_WriteByte(&net_message, CCREP_PLAYER_INFO);
  912.         MSG_WriteByte(&net_message, playerNumber);
  913.         MSG_WriteString(&net_message, client->name);
  914.         MSG_WriteLong(&net_message, client->colors);
  915.         MSG_WriteLong(&net_message, (int)client->edict->v.frags);
  916.         MSG_WriteLong(&net_message, (int)(net_time - client->netconnection->connecttime));
  917.         MSG_WriteString(&net_message, client->netconnection->address);
  918.         *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
  919.         dfunc.Write (acceptsock, net_message.data, net_message.cursize, &clientaddr);
  920.         SZ_Clear(&net_message);
  921.  
  922.         return NULL;
  923.     }
  924.  
  925.     if (command == CCREQ_RULE_INFO)
  926.     {
  927.         char    *prevCvarName;
  928.         cvar_t    *var;
  929.  
  930.         // find the search start location
  931.         prevCvarName = MSG_ReadString();
  932.         if (*prevCvarName)
  933.         {
  934.             var = Cvar_FindVar (prevCvarName);
  935.             if (!var)
  936.                 return NULL;
  937.             var = var->next;
  938.         }
  939.         else
  940.             var = cvar_vars;
  941.  
  942.         // search for the next server cvar
  943.         while (var)
  944.         {
  945.             if (var->server)
  946.                 break;
  947.             var = var->next;
  948.         }
  949.  
  950.         // send the response
  951.  
  952.         SZ_Clear(&net_message);
  953.         // save space for the header, filled in later
  954.         MSG_WriteLong(&net_message, 0);
  955.         MSG_WriteByte(&net_message, CCREP_RULE_INFO);
  956.         if (var)
  957.         {
  958.             MSG_WriteString(&net_message, var->name);
  959.             MSG_WriteString(&net_message, var->string);
  960.         }
  961.         *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
  962.         dfunc.Write (acceptsock, net_message.data, net_message.cursize, &clientaddr);
  963.         SZ_Clear(&net_message);
  964.  
  965.         return NULL;
  966.     }
  967.  
  968.     if (command != CCREQ_CONNECT)
  969.         return NULL;
  970.  
  971.     if (Q_strcmp(MSG_ReadString(), "QUAKE") != 0)
  972.         return NULL;
  973.  
  974.     if (MSG_ReadByte() != NET_PROTOCOL_VERSION)
  975.     {
  976.         SZ_Clear(&net_message);
  977.         // save space for the header, filled in later
  978.         MSG_WriteLong(&net_message, 0);
  979.         MSG_WriteByte(&net_message, CCREP_REJECT);
  980.         MSG_WriteString(&net_message, "Incompatible version.\n");
  981.         *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
  982.         dfunc.Write (acceptsock, net_message.data, net_message.cursize, &clientaddr);
  983.         SZ_Clear(&net_message);
  984.         return NULL;
  985.     }
  986.  
  987. #ifdef BAN_TEST
  988.     // check for a ban
  989.     if (clientaddr.sa_family == AF_INET)
  990.     {
  991.         unsigned long testAddr;
  992.         testAddr = ((struct sockaddr_in *)&clientaddr)->sin_addr.s_addr;
  993.         if ((testAddr & banMask) == banAddr)
  994.         {
  995.             SZ_Clear(&net_message);
  996.             // save space for the header, filled in later
  997.             MSG_WriteLong(&net_message, 0);
  998.             MSG_WriteByte(&net_message, CCREP_REJECT);
  999.             MSG_WriteString(&net_message, "You have been banned.\n");
  1000.             *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
  1001.             dfunc.Write (acceptsock, net_message.data, net_message.cursize, &clientaddr);
  1002.             SZ_Clear(&net_message);
  1003.             return NULL;
  1004.         }
  1005.     }
  1006. #endif
  1007.  
  1008.     // see if this guy is already connected
  1009.     for (s = net_activeSockets; s; s = s->next)
  1010.     {
  1011.         if (s->driver != net_driverlevel)
  1012.             continue;
  1013.         ret = dfunc.AddrCompare(&clientaddr, &s->addr);
  1014.         if (ret >= 0)
  1015.         {
  1016.             // is this a duplicate connection reqeust?
  1017.             if (ret == 0 && net_time - s->connecttime < 2.0)
  1018.             {
  1019.                 // yes, so send a duplicate reply
  1020.                 SZ_Clear(&net_message);
  1021.                 // save space for the header, filled in later
  1022.                 MSG_WriteLong(&net_message, 0);
  1023.                 MSG_WriteByte(&net_message, CCREP_ACCEPT);
  1024.                 dfunc.GetSocketAddr(s->socket, &newaddr);
  1025.                 MSG_WriteLong(&net_message, dfunc.GetSocketPort(&newaddr));
  1026.                 *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
  1027.                 dfunc.Write (acceptsock, net_message.data, net_message.cursize, &clientaddr);
  1028.                 SZ_Clear(&net_message);
  1029.                 return NULL;
  1030.             }
  1031.             // it's somebody coming back in from a crash/disconnect
  1032.             // so close the old qsocket and let their retry get them back in
  1033.             NET_Close(s);
  1034.             return NULL;
  1035.         }
  1036.     }
  1037.  
  1038.     // allocate a QSocket
  1039.     sock = NET_NewQSocket ();
  1040.     if (sock == NULL)
  1041.     {
  1042.         // no room; try to let him know
  1043.         SZ_Clear(&net_message);
  1044.         // save space for the header, filled in later
  1045.         MSG_WriteLong(&net_message, 0);
  1046.         MSG_WriteByte(&net_message, CCREP_REJECT);
  1047.         MSG_WriteString(&net_message, "Server is full.\n");
  1048.         *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
  1049.         dfunc.Write (acceptsock, net_message.data, net_message.cursize, &clientaddr);
  1050.         SZ_Clear(&net_message);
  1051.         return NULL;
  1052.     }
  1053.  
  1054.     // allocate a network socket
  1055.     newsock = dfunc.OpenSocket(0);
  1056.     if (newsock == -1)
  1057.     {
  1058.         NET_FreeQSocket(sock);
  1059.         return NULL;
  1060.     }
  1061.  
  1062.     // connect to the client
  1063.     if (dfunc.Connect (newsock, &clientaddr) == -1)
  1064.     {
  1065.         dfunc.CloseSocket(newsock);
  1066.         NET_FreeQSocket(sock);
  1067.         return NULL;
  1068.     }
  1069.  
  1070.     // everything is allocated, just fill in the details    
  1071.     sock->socket = newsock;
  1072.     sock->landriver = net_landriverlevel;
  1073.     sock->addr = clientaddr;
  1074.     Q_strcpy(sock->address, dfunc.AddrToString(&clientaddr));
  1075.  
  1076.     // send him back the info about the server connection he has been allocated
  1077.     SZ_Clear(&net_message);
  1078.     // save space for the header, filled in later
  1079.     MSG_WriteLong(&net_message, 0);
  1080.     MSG_WriteByte(&net_message, CCREP_ACCEPT);
  1081.     dfunc.GetSocketAddr(newsock, &newaddr);
  1082.     MSG_WriteLong(&net_message, dfunc.GetSocketPort(&newaddr));
  1083. //    MSG_WriteString(&net_message, dfunc.AddrToString(&newaddr));
  1084.     *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
  1085.     dfunc.Write (acceptsock, net_message.data, net_message.cursize, &clientaddr);
  1086.     SZ_Clear(&net_message);
  1087.  
  1088.     return sock;
  1089. }
  1090.  
  1091. qsocket_t *Datagram_CheckNewConnections (void)
  1092. {
  1093.     qsocket_t *ret = NULL;
  1094.  
  1095.     for (net_landriverlevel = 0; net_landriverlevel < net_numlandrivers; net_landriverlevel++)
  1096.         if (net_landrivers[net_landriverlevel].initialized)
  1097.             if ((ret = _Datagram_CheckNewConnections ()) != NULL)
  1098.                 break;
  1099.     return ret;
  1100. }
  1101.  
  1102.  
  1103. static void _Datagram_SearchForHosts (qboolean xmit)
  1104. {
  1105.     int        ret;
  1106.     int        n;
  1107.     int        i;
  1108.     struct qsockaddr readaddr;
  1109.     struct qsockaddr myaddr;
  1110.     int        control;
  1111.  
  1112.     dfunc.GetSocketAddr (dfunc.controlSock, &myaddr);
  1113.     if (xmit)
  1114.     {
  1115.         SZ_Clear(&net_message);
  1116.         // save space for the header, filled in later
  1117.         MSG_WriteLong(&net_message, 0);
  1118.         MSG_WriteByte(&net_message, CCREQ_SERVER_INFO);
  1119.         MSG_WriteString(&net_message, "QUAKE");
  1120.         MSG_WriteByte(&net_message, NET_PROTOCOL_VERSION);
  1121.         *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
  1122.         dfunc.Broadcast(dfunc.controlSock, net_message.data, net_message.cursize);
  1123.         SZ_Clear(&net_message);
  1124.     }
  1125.  
  1126.     while ((ret = dfunc.Read (dfunc.controlSock, net_message.data, net_message.maxsize, &readaddr)) > 0)
  1127.     {
  1128.         if (ret < sizeof(int))
  1129.             continue;
  1130.         net_message.cursize = ret;
  1131.  
  1132.         // don't answer our own query
  1133.         if (dfunc.AddrCompare(&readaddr, &myaddr) >= 0)
  1134.             continue;
  1135.  
  1136.         // is the cache full?
  1137.         if (hostCacheCount == HOSTCACHESIZE)
  1138.             continue;
  1139.  
  1140.         MSG_BeginReading ();
  1141.         control = BigLong(*((int *)net_message.data));
  1142.         MSG_ReadLong();
  1143.         if (control == -1)
  1144.             continue;
  1145.         if ((control & (~NETFLAG_LENGTH_MASK)) !=  NETFLAG_CTL)
  1146.             continue;
  1147.         if ((control & NETFLAG_LENGTH_MASK) != ret)
  1148.             continue;
  1149.  
  1150.         if (MSG_ReadByte() != CCREP_SERVER_INFO)
  1151.             continue;
  1152.  
  1153.         dfunc.GetAddrFromName(MSG_ReadString(), &readaddr);
  1154.         // search the cache for this server
  1155.         for (n = 0; n < hostCacheCount; n++)
  1156.             if (dfunc.AddrCompare(&readaddr, &hostcache[n].addr) == 0)
  1157.                 break;
  1158.  
  1159.         // is it already there?
  1160.         if (n < hostCacheCount)
  1161.             continue;
  1162.  
  1163.         // add it
  1164.         hostCacheCount++;
  1165.         Q_strcpy(hostcache[n].name, MSG_ReadString());
  1166.         Q_strcpy(hostcache[n].map, MSG_ReadString());
  1167.         hostcache[n].users = MSG_ReadByte();
  1168.         hostcache[n].maxusers = MSG_ReadByte();
  1169.         if (MSG_ReadByte() != NET_PROTOCOL_VERSION)
  1170.         {
  1171.             Q_strcpy(hostcache[n].cname, hostcache[n].name);
  1172.             hostcache[n].cname[14] = 0;
  1173.             Q_strcpy(hostcache[n].name, "*");
  1174.             Q_strcat(hostcache[n].name, hostcache[n].cname);
  1175.         }
  1176.         Q_memcpy(&hostcache[n].addr, &readaddr, sizeof(struct qsockaddr));
  1177.         hostcache[n].driver = net_driverlevel;
  1178.         hostcache[n].ldriver = net_landriverlevel;
  1179.         Q_strcpy(hostcache[n].cname, dfunc.AddrToString(&readaddr));
  1180.  
  1181.         // check for a name conflict
  1182.         for (i = 0; i < hostCacheCount; i++)
  1183.         {
  1184.             if (i == n)
  1185.                 continue;
  1186.             if (Q_strcasecmp (hostcache[n].name, hostcache[i].name) == 0)
  1187.             {
  1188.                 i = Q_strlen(hostcache[n].name);
  1189.                 if (i < 15 && hostcache[n].name[i-1] > '8')
  1190.                 {
  1191.                     hostcache[n].name[i] = '0';
  1192.                     hostcache[n].name[i+1] = 0;
  1193.                 }
  1194.                 else
  1195.                     hostcache[n].name[i-1]++;
  1196.                 i = -1;
  1197.             }
  1198.         }
  1199.     }
  1200. }
  1201.  
  1202. void Datagram_SearchForHosts (qboolean xmit)
  1203. {
  1204.     for (net_landriverlevel = 0; net_landriverlevel < net_numlandrivers; net_landriverlevel++)
  1205.     {
  1206.         if (hostCacheCount == HOSTCACHESIZE)
  1207.             break;
  1208.         if (net_landrivers[net_landriverlevel].initialized)
  1209.             _Datagram_SearchForHosts (xmit);
  1210.     }
  1211. }
  1212.  
  1213.  
  1214. static qsocket_t *_Datagram_Connect (char *host)
  1215. {
  1216.     struct qsockaddr sendaddr;
  1217.     struct qsockaddr readaddr;
  1218.     qsocket_t    *sock;
  1219.     int            newsock;
  1220.     int            ret;
  1221.     int            reps;
  1222.     double        start_time;
  1223.     int            control;
  1224.     char        *reason;
  1225.  
  1226.     // see if we can resolve the host name
  1227.     if (dfunc.GetAddrFromName(host, &sendaddr) == -1)
  1228.         return NULL;
  1229.  
  1230.     newsock = dfunc.OpenSocket (0);
  1231.     if (newsock == -1)
  1232.         return NULL;
  1233.  
  1234.     sock = NET_NewQSocket ();
  1235.     if (sock == NULL)
  1236.         goto ErrorReturn2;
  1237.     sock->socket = newsock;
  1238.     sock->landriver = net_landriverlevel;
  1239.  
  1240.     // connect to the host
  1241.     if (dfunc.Connect (newsock, &sendaddr) == -1)
  1242.         goto ErrorReturn;
  1243.  
  1244.     // send the connection request
  1245.     Con_Printf("trying...\n"); SCR_UpdateScreen ();
  1246.     start_time = net_time;
  1247.  
  1248.     for (reps = 0; reps < 3; reps++)
  1249.     {
  1250.         SZ_Clear(&net_message);
  1251.         // save space for the header, filled in later
  1252.         MSG_WriteLong(&net_message, 0);
  1253.         MSG_WriteByte(&net_message, CCREQ_CONNECT);
  1254.         MSG_WriteString(&net_message, "QUAKE");
  1255.         MSG_WriteByte(&net_message, NET_PROTOCOL_VERSION);
  1256.         *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
  1257.         dfunc.Write (newsock, net_message.data, net_message.cursize, &sendaddr);
  1258.         SZ_Clear(&net_message);
  1259.         do
  1260.         {
  1261.             ret = dfunc.Read (newsock, net_message.data, net_message.maxsize, &readaddr);
  1262.             // if we got something, validate it
  1263.             if (ret > 0)
  1264.             {
  1265.                 // is it from the right place?
  1266.                 if (sfunc.AddrCompare(&readaddr, &sendaddr) != 0)
  1267.                 {
  1268. #ifdef DEBUG
  1269.                     Con_Printf("wrong reply address\n");
  1270.                     Con_Printf("Expected: %s\n", dfunc.AddrToString (&sendaddr));
  1271.                     Con_Printf("Received: %s\n", dfunc.AddrToString (&readaddr));
  1272.                     SCR_UpdateScreen ();
  1273. #endif
  1274.                     ret = 0;
  1275.                     continue;
  1276.                 }
  1277.  
  1278.                 if (ret < sizeof(int))
  1279.                 {
  1280.                     ret = 0;
  1281.                     continue;
  1282.                 }
  1283.  
  1284.                 net_message.cursize = ret;
  1285.                 MSG_BeginReading ();
  1286.  
  1287.                 control = BigLong(*((int *)net_message.data));
  1288.                 MSG_ReadLong();
  1289.                 if (control == -1)
  1290.                 {
  1291.                     ret = 0;
  1292.                     continue;
  1293.                 }
  1294.                 if ((control & (~NETFLAG_LENGTH_MASK)) !=  NETFLAG_CTL)
  1295.                 {
  1296.                     ret = 0;
  1297.                     continue;
  1298.                 }
  1299.                 if ((control & NETFLAG_LENGTH_MASK) != ret)
  1300.                 {
  1301.                     ret = 0;
  1302.                     continue;
  1303.                 }
  1304.             }
  1305.         }
  1306.         while (ret == 0 && (SetNetTime() - start_time) < 2.5);
  1307.         if (ret)
  1308.             break;
  1309.         Con_Printf("still trying...\n"); SCR_UpdateScreen ();
  1310.         start_time = SetNetTime();
  1311.     }
  1312.  
  1313.     if (ret == 0)
  1314.     {
  1315.         reason = "No Response";
  1316.         Con_Printf("%s\n", reason);
  1317.         Q_strcpy(m_return_reason, reason);
  1318.         goto ErrorReturn;
  1319.     }
  1320.  
  1321.     if (ret == -1)
  1322.     {
  1323.         reason = "Network Error";
  1324.         Con_Printf("%s\n", reason);
  1325.         Q_strcpy(m_return_reason, reason);
  1326.         goto ErrorReturn;
  1327.     }
  1328.  
  1329.     ret = MSG_ReadByte();
  1330.     if (ret == CCREP_REJECT)
  1331.     {
  1332.         reason = MSG_ReadString();
  1333.         Con_Printf(reason);
  1334.         Q_strncpy(m_return_reason, reason, 31);
  1335.         goto ErrorReturn;
  1336.     }
  1337.  
  1338.     if (ret == CCREP_ACCEPT)
  1339.     {
  1340.         Q_memcpy(&sock->addr, &sendaddr, sizeof(struct qsockaddr));
  1341.         dfunc.SetSocketPort (&sock->addr, MSG_ReadLong());
  1342.     }
  1343.     else
  1344.     {
  1345.         reason = "Bad Response";
  1346.         Con_Printf("%s\n", reason);
  1347.         Q_strcpy(m_return_reason, reason);
  1348.         goto ErrorReturn;
  1349.     }
  1350.  
  1351.     dfunc.GetNameFromAddr (&sendaddr, sock->address);
  1352.  
  1353.     Con_Printf ("Connection accepted\n");
  1354.     sock->lastMessageTime = SetNetTime();
  1355.  
  1356.     // switch the connection to the specified address
  1357.     if (dfunc.Connect (newsock, &sock->addr) == -1)
  1358.     {
  1359.         reason = "Connect to Game failed";
  1360.         Con_Printf("%s\n", reason);
  1361.         Q_strcpy(m_return_reason, reason);
  1362.         goto ErrorReturn;
  1363.     }
  1364.  
  1365.     m_return_onerror = false;
  1366.     return sock;
  1367.  
  1368. ErrorReturn:
  1369.     NET_FreeQSocket(sock);
  1370. ErrorReturn2:
  1371.     dfunc.CloseSocket(newsock);
  1372.     if (m_return_onerror)
  1373.     {
  1374.         key_dest = key_menu;
  1375.         m_state = m_return_state;
  1376.         m_return_onerror = false;
  1377.     }
  1378.     return NULL;
  1379. }
  1380.  
  1381. qsocket_t *Datagram_Connect (char *host)
  1382. {
  1383.     qsocket_t *ret = NULL;
  1384.  
  1385.     for (net_landriverlevel = 0; net_landriverlevel < net_numlandrivers; net_landriverlevel++)
  1386.         if (net_landrivers[net_landriverlevel].initialized)
  1387.             if ((ret = _Datagram_Connect (host)) != NULL)
  1388.                 break;
  1389.     return ret;
  1390. }
  1391.